﻿using IServices;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using ViewModel.Auth;
using ViewModel.Response;

namespace Management.Controllers
{
    [Produces("application/json")]
    [Route("api/auth")]
    [ApiController]
    [AllowAnonymous]
    public class AuthenticationController : ControllerBase
    {
        private IAccountService accountService;
        private IAuthTokenService tokenService;
        private IConfiguration configuration;
        private IAccountRoleService accountRoleService;
        private AuthConfiguration jwtConfiguration = new AuthConfiguration();

        public AuthenticationController(IAccountService accountService,
                                        IAuthTokenService tokenService,
                                        IAccountRoleService accountRoleService,
                                        IConfiguration configuration)
        {
            this.accountService = accountService;
            this.tokenService = tokenService;
            this.configuration = configuration;
            this.accountRoleService = accountRoleService;
            this.configuration.GetSection("JWT").Bind(jwtConfiguration);
        }
        /// <summary>
        /// 获取身份凭据
        /// </summary>
        /// <param name="authModel">认证模型</param>
        /// <returns></returns>
        [HttpPost("token")]
        [Produces("application/json")]
        public ResponseModel<AccessToken> GetAccessToken([FromBody]AuthModel authModel)
        {
            var result = new ResponseModel<AccessToken>
            {
                Status = ResponseStatus.Fail
            };
            if (accountService.Login(authModel))
            {
                var user = accountService.Query(x => x.UserName == authModel.UserName).First();
                var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name,user.Name),
                    new Claim(ClaimTypes.NameIdentifier,user.Id.ToString()),
                };
                var userRoles = accountRoleService.QueryRole(user.Id);
                claims.AddRange(userRoles.Select(x => new Claim(ClaimTypes.Role, x.RoleName)));
                var token = new AccessToken
                {
                    Access_Token = tokenService.GenerateToken(claims),
                    Refresh_Token = tokenService.GenerateRefreshToken(),
                    Expired = jwtConfiguration.Expired,
                    UserName = authModel.UserName,
                };
                tokenService.AddToken(token);
                result.Status = ResponseStatus.OK;
                result.Data = token;
            }
            else
            {
                result.Status = ResponseStatus.Fail;
            }
            return result;
        }
        /// <summary>
        /// 刷新身份凭据
        /// </summary>
        /// <param name="accessToken">原始AccessToken</param>
        /// <returns></returns>
        [HttpPost("refresh")]
        [Produces("application/json")]
        public ResponseModel<AccessToken> RefreshToken([FromBody]AccessTokenBase accessToken)
        {
            var result = new ResponseModel<AccessToken>
            {
                Status = ResponseStatus.Fail
            };
            var principalClaims = tokenService.GetPrincipalFromExpiredToken(accessToken.Access_Token);
            var token = new AccessToken
            {
                Access_Token = tokenService.GenerateToken(principalClaims.Claims, true),
                Refresh_Token = tokenService.GenerateRefreshToken(),
                Expired = jwtConfiguration.RefreshExpired,
                UserName = principalClaims.Claims.Where(x => x.Type == ClaimTypes.Name).Select(x => x.Value).FirstOrDefault(),
            };
            tokenService.Update(accessToken, token);
            result.Status = ResponseStatus.OK;
            result.Data = token;
            return result;
        }

    }
}